#include "mqtt_aliot.h"
#define MQTT_TAG "MQTT_ALIOT"
//信号量
static SemaphoreHandle_t   s_mqtt_sem = NULL;

static char s_is_connected_mqtt = 0;
static esp_mqtt_client_handle_t mqtt_handle = NULL; 
extern const char*  g_aliot_ca ;
char* get_clientid()
{
    uint8_t mac[6];
    static char client_id[32] = {0};
    esp_wifi_get_mac(WIFI_IF_STA, mac);
    snprintf(client_id, sizeof(client_id), "%02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
    return client_id;
}

void cal_md5(char * key , char* content,unsigned char * output)
{
    mbedtls_md_context_t md5_ctx;
    const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_MD5);
    mbedtls_md_init(&md5_ctx);
    mbedtls_md_setup(&md5_ctx, md_info, 1);
    mbedtls_md_hmac_starts(&md5_ctx,(const unsigned char*)key,strlen(key));
    mbedtls_md_hmac_update(&md5_ctx,(const unsigned char*)content,strlen(content));
    mbedtls_md_hmac_finish(&md5_ctx,output);
    mbedtls_md_free(&md5_ctx);
}

void hex2str(uint8_t * input,uint32_t input_len,char * output)
{
    char * upper = "0123456789ABCDEF";
    int i=0,j=0;
    
    for(i=0;i<input_len;i++)
    {
        output[j++] = upper[(input[i]>>4)&0xF];
        output[j++] = upper[input[i]&0xF];
    }
    output[j] = 0;
}
char  is_connected_mqtt()
{
    return s_is_connected_mqtt;
}

//mqtt事件回调函数
void mqtt_event_callback(void* event_handler_arg, esp_event_base_t event_base,int32_t event_id,void* event_data)
{

    //返回的数据
    esp_mqtt_event_handle_t data = (esp_mqtt_event_handle_t)event_data;
    switch(event_id){
        case MQTT_EVENT_CONNECTED:
            xSemaphoreGive(s_mqtt_sem); //连接成功 释放信号量
             s_is_connected_mqtt = 1;
            ESP_LOGI(MQTT_TAG, "MQTT_EVENT_CONNECTED");
            break;
        case MQTT_EVENT_DISCONNECTED:
            s_is_connected_mqtt = 0;
            ESP_LOGI(MQTT_TAG, "MQTT_EVENT_DISCONNECTED");
            break;
        case MQTT_EVENT_PUBLISHED:
            //ESP_LOGI(MQTT_TAG, "MQTT_EVENT_PUBLISHED ACK");
            break;
        case MQTT_EVENT_SUBSCRIBED:
            ESP_LOGI(MQTT_TAG, "MQTT_EVENT_SUBSCRIBED ACK");
            break;
        case MQTT_EVENT_DATA:

        // 解析当前主题
            ESP_LOGI(MQTT_TAG,"topic:%.*s",data->topic_len,data->topic); //传输的主题
            ESP_LOGI(MQTT_TAG,"payload:%*s",data->data_len,data->data); //payload是MQTT中实际传输的数据
            post_ctrl_data(data);

            break;
        default:
            break;
    }

}

void aliot_start()
{
    esp_mqtt_client_config_t mqtt_cfg = {0}; 

    mqtt_cfg.broker.address.uri = ALIOT_MQTT_URL;
    mqtt_cfg.broker.address.port = 8883;
    //client_id
    char client_id[128] = {0};
    snprintf(client_id,sizeof(client_id),"%s|securemode=2,signmethod=hmacmd5|",get_clientid());

    mqtt_cfg.credentials.client_id = client_id;
    //username = deviceName+"&"+productKey
    char username[128] = {0};
    snprintf(username,sizeof(username),"%s&%s",ALIOT_DEVICENAME,ALIOT_PRRODUCUTKEY);
    mqtt_cfg.credentials.username = username;


    //password
    //mqttPassword=hmacsha1("secret","clientId12345deviceNamedeviceproductKeypktimestamp789").toHexString(); 
    char sign_content[256] = {0};
    snprintf(sign_content,sizeof(sign_content),"clientId%sdeviceName%sproductKey%s",get_clientid(),ALIOT_DEVICENAME,ALIOT_PRRODUCUTKEY);
    unsigned char password_hex[16];
    char password_str[33];
    cal_md5(ALIOT_DEVICESECRET,sign_content,password_hex);
    hex2str(password_hex,16,password_str);
    mqtt_cfg.credentials.authentication.password = password_str;

    //TLS证书
    mqtt_cfg.broker.verification.certificate = g_aliot_ca;

    mqtt_handle = esp_mqtt_client_init(&mqtt_cfg);
    s_mqtt_sem = xSemaphoreCreateBinary(); //创建信号量
    esp_mqtt_client_register_event(mqtt_handle, ESP_EVENT_ANY_ID, mqtt_event_callback, NULL);
    esp_mqtt_client_start(mqtt_handle);
    ESP_LOGI(MQTT_TAG, "MQTT_ALIOT waiting for connect");
    xSemaphoreTake(s_mqtt_sem,portMAX_DELAY); //等待信号量连接成功,阻塞线程
}

void aliot_post_property_float(const char* name,float value)
{
    ALIOT_DM_DES *dm = aliot_malloc_des(ALIOT_DM_POST);
    aliot_set_dm_float(dm, name, value); 
    aliot_dm_serialize(dm);
    char topic[128] = {0};
    snprintf(topic,sizeof(topic),"/sys/%s/%s/thing/event/property/post",ALIOT_PRRODUCUTKEY,ALIOT_DEVICENAME);
    esp_mqtt_client_publish(mqtt_handle, topic, dm->dm_js_str, strlen(dm->dm_js_str), 1, 0);
    aliot_dm_free(dm);
}

void aliot_post_property_int(const char* name,int value)
{
    ALIOT_DM_DES *dm = aliot_malloc_des(ALIOT_DM_POST);
    aliot_set_dm_int(dm, name, value); 
    aliot_dm_serialize(dm);
    char topic[128] = {0};
    snprintf(topic,sizeof(topic),"/sys/%s/%s/thing/event/property/post",ALIOT_PRRODUCUTKEY,ALIOT_DEVICENAME);
    esp_mqtt_client_publish(mqtt_handle, topic, dm->dm_js_str, strlen(dm->dm_js_str), 1, 0);
    aliot_dm_free(dm);
}

void aliot_property_ack(int code,const char* message)
{
    ALIOT_DM_DES *dm = aliot_malloc_des(ALIOT_DM_SET_ACK);
    aliot_set_dm_property_ack(dm, code, message); 
    aliot_dm_serialize(dm);
    char topic[128] = {0};
    snprintf(topic,sizeof(topic),"/sys/%s/%s/thing/service/property/set_ack",ALIOT_PRRODUCUTKEY,ALIOT_DEVICENAME);
    esp_mqtt_client_publish(mqtt_handle, topic, dm->dm_js_str, strlen(dm->dm_js_str), 1, 0);
    aliot_dm_free(dm);
    
}



const char*  g_aliot_ca = "-----BEGIN CERTIFICATE-----\n"
"MIID3zCCAsegAwIBAgISfiX6mTa5RMUTGSC3rQhnestIMA0GCSqGSIb3DQEBCwUA"
"MHcxCzAJBgNVBAYTAkNOMREwDwYDVQQIDAhaaGVqaWFuZzERMA8GA1UEBwwISGFu"
"Z3pob3UxEzARBgNVBAoMCkFsaXl1biBJb1QxEDAOBgNVBAsMB1Jvb3QgQ0ExGzAZ"
"BgNVBAMMEkFsaXl1biBJb1QgUm9vdCBDQTAgFw0yMzA3MDQwNjM2NThaGA8yMDUz"
"MDcwNDA2MzY1OFowdzELMAkGA1UEBhMCQ04xETAPBgNVBAgMCFpoZWppYW5nMREw"
"DwYDVQQHDAhIYW5nemhvdTETMBEGA1UECgwKQWxpeXVuIElvVDEQMA4GA1UECwwH"
"Um9vdCBDQTEbMBkGA1UEAwwSQWxpeXVuIElvVCBSb290IENBMIIBIjANBgkqhkiG"
"9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoK//6vc2oXhnvJD7BVhj6grj7PMlN2N4iNH4"
"GBmLmMdkF1z9eQLjksYc4Zid/FX67ypWFtdycOei5ec0X00m53Gvy4zLGBo2uKgi"
"T9IxMudmt95bORZbaph4VK82gPNU4ewbiI1q2loRZEHRdyPORTPpvNLHu8DrYBnY"
"Vg5feEYLLyhxg5M1UTrT/30RggHpaa0BYIPxwsKyylQ1OskOsyZQeOyPe8t8r2D4"
"RBpUGc5ix4j537HYTKSyK3Hv57R7w1NzKtXoOioDOm+YySsz9sTLFajZkUcQci4X"
"aedyEeguDLAIUKiYicJhRCZWljVlZActorTgjCY4zRajodThrQIDAQABo2MwYTAO"
"BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUkWHoKi2h"
"DlS1/rYpcT/Ue+aKhP8wHwYDVR0jBBgwFoAUkWHoKi2hDlS1/rYpcT/Ue+aKhP8w"
"DQYJKoZIhvcNAQELBQADggEBADrrLcBY7gDXN8/0KHvPbGwMrEAJcnF9z4MBxRvt"
"rEoRxhlvRZzPi7w/868xbipwwnksZsn0QNIiAZ6XzbwvIFG01ONJET+OzDy6ZqUb"
"YmJI09EOe9/Hst8Fac2D14Oyw0+6KTqZW7WWrP2TAgv8/Uox2S05pCWNfJpRZxOv"
"Lr4DZmnXBJCMNMY/X7xpcjylq+uCj118PBobfH9Oo+iAJ4YyjOLmX3bflKIn1Oat"
"vdJBtXCj3phpfuf56VwKxoxEVR818GqPAHnz9oVvye4sQqBp/2ynrKFxZKUaJtk0"
"7UeVbtecwnQTrlcpWM7ACQC0OO0M9+uNjpKIbksv1s11xu0=\n"
"-----END CERTIFICATE-----";

